﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration;
using System.Reflection;
using System.ServiceModel.Configuration;
using Stone.Library.Common;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace Stone.Host
{
    public class ServiceHostGroup
    {
        static List<ServiceHost> _hosts = new List<ServiceHost>();

        private static void OpenHost(Type t)
        {
            ServiceHost hst = new ServiceHost(t);
            hst.Open();
            #region debug
            //DisplayAllEndpointLogicalAndPhysicalUri(hst);
            foreach (ServiceEndpoint se in hst.Description.Endpoints)
            {
                Console.WriteLine("Endpoint details:");
                Console.WriteLine("Logical address: \t{0}", se.Address);
                Console.WriteLine("Physical address: \t{0}", se.ListenUri);
                Console.WriteLine("Binding: \t{0}", se.Binding.Name);
            }
            #endregion
            _hosts.Add(hst);
        }

        public static void StartAllConfiguredServices()
        {
            Configuration conf = System.Configuration.ConfigurationManager.OpenExeConfiguration(Assembly.GetExecutingAssembly().Location);
            ServiceModelSectionGroup svcmod =(ServiceModelSectionGroup)conf.GetSectionGroup("system.serviceModel");
            string AssemblyStr = ", Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";
            foreach (ServiceElement el in svcmod.Services.Services)
            {
                string[] tmp = el.Name.Split('.');
                tmp[0] += "."+tmp[1]+AssemblyStr;

                Type svcType = Type.GetType(el.Name + "," + tmp[0]);
                if (svcType == null)
                {
                    string errorMsg = "Invalid Service Type " + el.Name + " in configuration file.";
                    LogManger.WriteErrorLogWin(errorMsg);
                    throw new Exception(errorMsg);
                }
                OpenHost(svcType);
                Console.WriteLine("<<<<<<<<<Host-- {0}--Started>>>>>>>>>>\n\t", svcType.Name);
            }
        }

        public static void CloseAllServices()
        {
            foreach (ServiceHost hst in _hosts)
            {
                hst.Close();
            }
            _hosts = new List<ServiceHost>();
        }

        #region 测试
        private static void DisplayAllEndpointLogicalAndPhysicalUri(ServiceHost host)
        {
            foreach (ChannelDispatcher cd in host.ChannelDispatchers)
            {
                Console.WriteLine("--------------------当前信道分发器信息--------------------\n"); 
                Console.WriteLine("监听的物理地址：{0}\n", cd.Listener.Uri.ToString()); 
                Console.WriteLine("终结点列表:\n"); 
                foreach (EndpointDispatcher ed in cd.Endpoints) {
                    Console.WriteLine("终结点逻辑地址：{0}", ed.EndpointAddress.Uri.ToString());
                }

                Console.WriteLine();
            }

            Console.WriteLine();
        }
        #endregion
    }
}
